﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BuildPlannerLib.Buildings;
using BuildPlannerLib.PlayerActions;
using BuildPlannerLib.SimEvents;
using BuildPlannerLib.Terran.Enums;

namespace BuildPlannerLib.PlayerActions
{
    // Derived class from Action for producing 3 level upgrades
    public class ProduceLevelUpgrade : PlayerAction
    {
        // Field for the upgrade being resourced
        public LevelUpgrade Upgrade;

        // Field for the production facility
        public IndividualBuilding Building;

        // Constructor with parameters for build and unit
        public ProduceLevelUpgrade(Build build, LevelUpgrade upgrade)
        {
            Build = build;
            Upgrade = upgrade;
            MineralCost = Upgrade.MineralCost;
            MineralCost += Upgrade.MineralCostScaling * Upgrade.LevelStarted;
            GasCost = Upgrade.GasCost;
            GasCost += Upgrade.GasCostScaling * Upgrade.LevelStarted;
            TimeDuration = Upgrade.TimeDuration;
            TimeDuration += Upgrade.TimeDurationScaling * Upgrade.LevelStarted;
            Description = "Research " + Upgrade.Name + " Level " + (Upgrade.LevelStarted + 1);
            LongDescription = "Researching the upgrade " + Upgrade.Name + " Level " + (Upgrade.LevelStarted + 1) + " at " + Upgrade.ProducedFrom;
        }

        // Evaluates whether the player is Terran, whether there is mineral income or enough minerals, whether there is gas income or enough gas,
        // whether the upgrade has started yet, whether the requirement building is started, and whether the production building is started
        public override bool RequirementsFilled()
        {
            ProductionBuilding building = Build.Player.GetBuilding(Upgrade.ProducedFrom) as ProductionBuilding;
            Building requirementBuilding = null;
            if (Upgrade.Requirement[Upgrade.LevelStarted] != null)
                requirementBuilding = Build.Player.GetBuilding(Upgrade.Requirement[Upgrade.LevelStarted]);
            Error = null;

            if (building.Started == 0)
            {
                Error = "There are no production facilities that can produce this upgrade.";
                return false;
            }

            if (requirementBuilding != null && requirementBuilding.Started == 0)
            {
                Error = "The required building \"" + Upgrade.Requirement[Upgrade.LevelStarted] + "\" has not been built.";
                return false;
            }

            if (Upgrade.LevelStarted > 2)
            {
                Error = "The upgrade cannot go above Level 3.";
                return false;
            }

            return base.RequirementsFilled();
        }

        // Evaluates if there are enough minerals, enough gas, the upgrade hasn't been started, requirement building is finished, and production facility is not in-use
        public override bool StartCheck()
        {
            ProductionBuilding building = Build.Player.GetBuilding(Upgrade.ProducedFrom) as ProductionBuilding;
            Building requirementBuilding = null;
            if (Upgrade.Requirement[Upgrade.LevelStarted] != null)
                requirementBuilding = Build.Player.GetBuilding(Upgrade.Requirement[Upgrade.LevelStarted]);

            if (Upgrade.LevelStarted < Upgrade.LevelFinished)
                return false;

            if (requirementBuilding != null && requirementBuilding.GetCount() == 0)
                return false;

            bool availableBuilding = building.IndividualBuildings.Exists(delegate(IndividualBuilding i)
            {
                return !i.InUse;
            });
            if (!availableBuilding)
                return false;

            return base.StartCheck();
        }

        // Spends the minerals, spends the gas, puts the production building in-use and adds the event to finish the action
        public override void StartAction()
        {
            ProductionBuilding building = Build.Player.GetBuilding(Upgrade.ProducedFrom) as ProductionBuilding;

            base.StartAction();

            Building = building.IndividualBuildings.Find(delegate(IndividualBuilding i)
            {
                return !i.InUse;
            });
            Building.StartProduction();
            Upgrade.LevelStarted++;
        }

        // Sets the production facility from being in-use and finishes the upgrade
        public override void FinishAction()
        {
            Building.FinishProduction();
            Upgrade.LevelFinished++;
        }
    }
}
